package com.lxd.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.lxd.entity.RegistrationVO;
import com.lxd.entity.TokenUserInfoDto;
import com.lxd.entity.enums.NotifyEnum;
import com.lxd.entity.po.*;
import com.lxd.entity.query.*;
import com.lxd.entity.vo.ActivityVO;
import com.lxd.exception.BusinessException;
import com.lxd.mappers.*;
import com.lxd.redis.RedisComponent;
import com.lxd.redis.RedisUtil;
import com.lxd.utils.CopyTools;
import org.springframework.stereotype.Service;

import com.lxd.entity.enums.PageSize;
import com.lxd.entity.vo.PaginationResultVO;
import com.lxd.service.RegistrationService;
import com.lxd.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;


/**
 * 业务接口实现
 */
@Service("registrationService")
public class RegistrationServiceImpl implements RegistrationService {

    @Resource
    private RegistrationMapper<Registration, RegistrationQuery> registrationMapper;
    @Resource
    private RedisComponent redisComponent;
    @Resource
    private UserMapper<User, UserQuery> userMapper;
    @Resource
    private RedisUtil redis;
    @Resource
    private ActivityMapper<Activity, ActivityQuery> activityMapper;
    @Resource
    private ClubMapper<Club, ClubQuery> clubMapper;
    @Resource
    private NotificationMapper<Notification, NotificationQuery> notificationMapper;

    /**
     * 根据条件查询列表
     */
    @Override
    public List<Registration> findListByParam(RegistrationQuery param) {
        return this.registrationMapper.selectList(param);
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(RegistrationQuery param) {
        return this.registrationMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResultVO<RegistrationVO> findListByPage(RegistrationQuery param, String token) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<Registration> list = this.findListByParam(param);
        List<RegistrationVO> registrationVOList = CopyTools.copyList(list, RegistrationVO.class);
        for (RegistrationVO registration : registrationVOList) {
            //从缓存中获取数据
            registration.setApplyedName(getApplyedName(registration));
            //设置申请者名称
            registration.setApplyUserName(getApplyUserName(registration.getUserId()));

        }
        PaginationResultVO<RegistrationVO> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), registrationVOList);
        return result;
    }

    /**
     * 设置被申请的活动or社团名称
     */
    private String getApplyedName(RegistrationVO vo) {
        String name = null;
        if (vo.getActivityId() != null) {
            name = redisComponent.getActivityNameById(vo.getActivityId());
            if (name == null) {
                Activity activity = activityMapper.selectById(vo.getActivityId());
                ActivityVO activityVO = CopyTools.copy(activity, ActivityVO.class);
                redis.setHash("ACTIVITY", activity.getId().toString(), activityVO);
                name = activity.getTitle();
            }
        } else if (vo.getClubId() != null) {
            name = redisComponent.getClubNameById(vo.getClubId());
            if (name == null) {
                Club club = clubMapper.selectById(vo.getClubId());
                redis.setHash("CLUB", club.getId().toString(), club);
                name = club.getName();
            }
        }
        return name;

    }

    private String getApplyUserName(Long id) {
        String userName = redisComponent.getUserNameById(id);
        if (userName == null) {
            User user = userMapper.selectByUserId(id);
            if (user == null) {
                return null;
            }
            userName = user.getUserRealName();
            redis.setHash("USER", user.getUserId().toString(), user);
        }
        return userName;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(Registration bean) {
        return this.registrationMapper.insert(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<Registration> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.registrationMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<Registration> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.registrationMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 多条件更新
     */
    @Override
    public Integer updateByParam(Registration bean, RegistrationQuery param) {
        StringTools.checkParam(param);
        return this.registrationMapper.updateByParam(bean, param);
    }

    /**
     * 多条件删除
     */
    @Override
    public Integer deleteByParam(RegistrationQuery param) {
        StringTools.checkParam(param);
        return this.registrationMapper.deleteByParam(param);
    }

    /**
     * 根据Id获取对象
     */
    @Override
    public Registration getRegistrationById(Long id) {
        return this.registrationMapper.selectById(id);
    }

    /**
     * 根据Id修改
     */
    @Override
    @Transactional
    public Integer updateRegistrationById(Registration bean, Long id) {
        bean.setUpdatedAt(new Date());
        this.registrationMapper.updateById(bean, id);
        // 通知对应用户
        notifyToUser(bean);
        return null;
    }

    private void notifyToUser(Registration bean) {
        Date date = new Date();
        Registration registration = getRegistrationById(bean.getId());
        Integer status = bean.getStatus();
        Long userId = registration.getUserId();
        Notification notification = new Notification();
        if (registration.getActivityId() != null) {
            String activityName = redisComponent.getActivityNameById(registration.getActivityId());
            String prefix=activityName+":";
            //审批通过
            if (status == 1) {
                notification.setContent(prefix+NotifyEnum.ApplyActivitySuccessNotify.getContent());
                notification.setTitle(prefix+NotifyEnum.ApplyActivitySuccessNotify.getTitle());
            } else if (status == 2) {
                notification.setContent(prefix+NotifyEnum.ApplyActivityFailedNotify.getContent());
                notification.setTitle(prefix+NotifyEnum.ApplyActivityFailedNotify.getTitle());
            }
        }else if (registration.getClubId()!=null){
            //获取社团名称
            String clubName = redisComponent.getClubNameById(registration.getClubId());
            String prefix=clubName+":";
            if (status == 1) {
                notification.setContent(prefix+NotifyEnum.ApplyClubSuccessNotify.getContent());
                notification.setTitle(prefix+NotifyEnum.ApplyClubSuccessNotify.getTitle());
            } else if (status == 2) {
                notification.setContent(prefix+NotifyEnum.ApplyClubFailedNotify.getContent());
                notification.setTitle(prefix+NotifyEnum.ApplyClubFailedNotify.getTitle());
            }
        }
        notification.setUserId(userId);
        notification.setIsRead(0);
        notification.setCreatedAt(date);
        notificationMapper.insert(notification);
    }

    /**
     * 根据Id删除
     */
    @Override
    public Integer deleteRegistrationById(Long id) {
        return this.registrationMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void join(RegistrationVO registrationVO, TokenUserInfoDto tokenUserInfoDto) {

        Long userId = Long.valueOf(tokenUserInfoDto.getUserId());

        Registration registration = registrationVO.getClubId() != null
                ?
                registrationMapper.selectCountByUserIdAndClubId(userId, registrationVO.getClubId())
                :
                registrationMapper.selectOneByUserIdAndActivityId(userId, registrationVO.getActivityId());
        //todo 枚举类
        if (registration != null && registration.getStatus() == 0) {
            throw new BusinessException("您已经申请过了~请耐心等待~");
        }
        if (registration != null && registration.getStatus() == 1) {
            throw new BusinessException("您正在其中~不要重复申请~");
        }
        Date date = new Date();
        //被拒绝过，重新申请的
        if (registration != null && registration.getStatus() == 2) {

            registration.setStatus(0);
            registration.setApplyContent(registrationVO.getApplyContent());
            registration.setUpdatedAt(date);
            registrationMapper.updateById(registration, registration.getId());
            return;
        }
        Registration entity = CopyTools.copy(registrationVO, Registration.class);
        entity.setUserId(userId);
        entity.setStatus(0);
        entity.setCreatedAt(date);
        entity.setUpdatedAt(date);
        registrationMapper.insert(entity);
    }
}